package com.cc.config;

import com.cc.config.security.CustomAccessDeniedHandler;
import com.cc.config.security.CustomAuthenticationEntryPoint;
import com.cc.config.security.JwtAuthenticationTokenFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * @ClassName: SecurityConfig
 * @Description:
 * @Author: 晓东√
 * @Date: 2024-12-16 10:39
 * @Version: 1.0
 **/
@Configuration
@EnableWebSecurity //自动应用默认的安全配置
public class SecurityConfig {
    @Autowired
    CustomAccessDeniedHandler customAccessDeniedHandler;
    @Autowired
    CustomAuthenticationEntryPoint customAuthenticationEntryPoint;

    @Autowired
    JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //1. 基本配置
        http
                .csrf(csrf -> csrf.disable()) //CSRF 保护被禁用
                .cors(cors -> cors.disable()); //CORS 保护被禁用。这允许任何来源的跨域请求。
        //2.会话配置
        http.sessionManagement(session ->
                //SessionCreationPolicy.
                // STATELESS:Spring Security永远不会创建HttpSession，它不会使用HttpSession来获取SecurityContext
                //ALWAYS:总是创建HttpSession
                //IF_REQUIRED:Spring Security只会在需要时创建一个HttpSession
                //NEVER:Spring Security不会创建HttpSession，但如果它已经存在，将可以使用HttpSession
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        );
        //3.请求授权
        http.authorizeHttpRequests(auth -> {
            auth
                    .requestMatchers(
                            "/user/login",
                            "/static/*",
                            "/css/**",
                            "/js/**",
                            "/webjars/**",
                            "/index.html",
                            "favicon.ico",
                            "/swagger-resources/**",
                            "/doc.html/**",
                            "/v3/api-docs/**",
                            "/swagger-ui/**"
                    ).permitAll()
                    .anyRequest().authenticated();
        });
        //4. // 异常处理
        http
                .exceptionHandling(exceptions -> exceptions
                        //权限异常
                        .accessDeniedHandler(customAccessDeniedHandler)
                        //认证异常
                        .authenticationEntryPoint(customAuthenticationEntryPoint)
                );
        //配置过滤器，在UsernamePasswordAuthenticationFilter之前
        http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManager(
            AuthenticationConfiguration config) throws Exception {
        return config.getAuthenticationManager();
    }
}
